package utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class TijdsMoment1Dag implements Comparable<TijdsMoment1Dag>, Cloneable {

	/**
	 * TijdsMoment1Dag class
	 * 
	 * @author Yves Vandeput
	 * @author Nicolas Vanderhulst
	 * @version 20111118
	 */

	private GregorianCalendar vanMoment;
	private GregorianCalendar totMoment;
	private static final int WEEK_START = 1700;
	private static final int WEEK_END = 2200;
	private static final int SAT_START = 900;
	private static final int SAT_END = 1400;

	/**
	 * 
	 * Getters en Setters
	 * 
	 */
	public void setVanMoment(GregorianCalendar vanM) {
		this.vanMoment = vanM;
	}

	public void setTotMoment(GregorianCalendar totM) {
		this.totMoment = totM;
	}

	public GregorianCalendar getVanMoment() {
		return this.vanMoment;
	}

	public GregorianCalendar getTotMoment() {
		return this.totMoment;
	}

	/**
	 * 
	 * Constructor
	 * 
	 */
	public TijdsMoment1Dag() {
		this.vanMoment = new GregorianCalendar();
		this.totMoment = new GregorianCalendar();
	}

	/**
	 * 
	 * Constructor met Gregoriancalender objecten
	 * 
	 */
	public TijdsMoment1Dag(GregorianCalendar van, GregorianCalendar tot) {
		this.vanMoment = van;
		this.totMoment = tot;
	}

	/**
	 * 
	 * Constructor met start tijdstip en duurtijd
	 * 
	 */
	@SuppressWarnings("boxing")
	public TijdsMoment1Dag(String lesDag, int uur, int minuut, int duur) {

		try {
			SimpleDateFormat sdf = new SimpleDateFormat("HHmm");
			int weekdag = 0;
			int startTijdstip;
			int eindTijdstip;
			for (LesDag l : LesDag.values()) {
				if (l.toString().equalsIgnoreCase(lesDag)) {
					weekdag = l.ordinal();
				}
			}
			GregorianCalendar tempStartMoment = new GregorianCalendar();
			tempStartMoment.set(Calendar.DAY_OF_WEEK, weekdag);
			tempStartMoment.set(Calendar.HOUR_OF_DAY, uur);
			tempStartMoment.set(Calendar.MINUTE, minuut);
			GregorianCalendar tempEindMoment = (GregorianCalendar) tempStartMoment.clone();
			tempEindMoment.add(Calendar.MINUTE, duur);
			startTijdstip = Integer.parseInt(sdf.format(tempStartMoment.getTime().getTime()));
			eindTijdstip = Integer.parseInt(sdf.format(tempEindMoment.getTime().getTime()));
			if ((tempStartMoment.get(Calendar.DAY_OF_YEAR) != tempEindMoment.get(Calendar.DAY_OF_YEAR))
					|| (tempStartMoment.get(Calendar.YEAR) != tempEindMoment.get(Calendar.YEAR))) {
				throw new IllegalArgumentException("De les moet op dezelfde dag eindigen.");
			} else if (!tempEindMoment.after(tempStartMoment)) {
				throw new IllegalArgumentException("Foutieve duur ingevoerd");
			}
			switch (weekdag) {
			case 0:
				throw new IllegalArgumentException("De ingegeven datum mag niet op een zondag vallen.");
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				if ((startTijdstip < WEEK_START) || (eindTijdstip > WEEK_END)) {
					throw new IllegalArgumentException("De lessen worden gepland op weekdagen tussen 17.00 en 22.00");
				} else {
					this.vanMoment = tempStartMoment;
					this.totMoment = tempEindMoment;
				}
				break;
			case 6:
				if ((startTijdstip < SAT_START) || (eindTijdstip > SAT_END)) {
					throw new IllegalArgumentException("De lessen worden gepland op zaterdag tussen 9.00 en 14.00");
				} else {
					this.vanMoment = tempStartMoment;
					this.totMoment = tempEindMoment;
				}
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * Geef aantal minuten tussen vanMoment en totMoment
	 * 
	 */
	public long getLengteInMinuten() {
		long lengte = 0;

		if (totMoment.after(this.vanMoment)) {
			lengte = (totMoment.getTimeInMillis()) - (vanMoment.getTimeInMillis());
			return (lengte / 1000) / 60; // Van miliseconden naar seconden - naar minuten
		} else {
			return -1; // Ongeldig tijdsinterval - throw exception?
		}
	}

	/**
	 * controleert of het actieve tijdsinterval overlapt met het parameter tijdsinterval
	 * 
	 */
	public boolean overlapt(TijdsMoment1Dag tijdsinterval) {
		// Als het huidige tijdsinterval start na het parameter tijdsinterval
		if (this.vanMoment.after(tijdsinterval.totMoment)) {
			return false;
		}

		// Als het huidige tijdsinterval eindigt voor de start van het parameter tijdsinterval
		if (this.totMoment.before(tijdsinterval.vanMoment)) {
			return false;
		}

		return true;
	}

	@SuppressWarnings("boxing")
	@Override
	public String toString() {
		LesDag[] lesdagen = LesDag.values();
		String lesdag = lesdagen[vanMoment.get(Calendar.DAY_OF_WEEK)].toString();
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
		String startTijdstip = sdf.format(vanMoment.getTime().getTime());
		return String.format("%s\t%s\tDuur: %s min", lesdag, startTijdstip, this.getLengteInMinuten());
	}

	@SuppressWarnings("boxing")
	public String toStringForListbox() {
		LesDag[] lesdagen = LesDag.values();
		String lesdag = lesdagen[vanMoment.get(Calendar.DAY_OF_WEEK)].toString();
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
		String startTijdstip = sdf.format(vanMoment.getTime().getTime());
		return String.format("%s  %s   Duur: %s min", lesdag, startTijdstip, this.getLengteInMinuten());
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((totMoment == null) ? 0 : totMoment.hashCode());
		result = prime * result + ((vanMoment == null) ? 0 : vanMoment.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		TijdsMoment1Dag other = (TijdsMoment1Dag) obj;
		if (totMoment == null) {
			if (other.totMoment != null) {
				return false;
			}
		} else if (!totMoment.equals(other.totMoment)) {
			return false;
		}
		if (vanMoment == null) {
			if (other.vanMoment != null) {
				return false;
			}
		} else if (!vanMoment.equals(other.vanMoment)) {
			return false;
		}
		return true;
	}

	@Override
	public int compareTo(TijdsMoment1Dag ti) {
		if (ti.equals(ti)) {
			return 0;
		} else {
			return -1;
		}
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return new TijdsMoment1Dag(this.vanMoment, this.totMoment);
	}

}
